package com.code.soulqlexpress.func;

import com.ql.util.express.ArraySwap;
import com.ql.util.express.InstructionSetContext;
import com.ql.util.express.OperateData;
import com.ql.util.express.instruction.op.OperatorBase;

import java.util.ArrayList;
import java.util.List;

/**
 * 表达式函数next_status
 * next_status(2,0,0) -> 0 表示第一个数据为全部
 * next_status(1,2,0) -> 1 表示第一个数据为一个
 * next_status(1,1,0) -> 1 表示第一个数据为一个
 * next_status(2,2,0) -> 1 表示第一个数据为部分
 *
 * @Author:jdy
 * @Date:2020/3/16
 * @Content:
 */
public class NextStatusOperator extends OperatorBase {

    private static final long serialVersionUID = -419116845679389408L;

    @Override
    public OperateData executeInner(InstructionSetContext instructionSetContext, ArraySwap arraySwap) throws Exception {
        //第一个参数
        final OperateData operateData = arraySwap.get(0);
        final Object object = operateData.getObject(instructionSetContext);

        int length = arraySwap.length;
        //参数必须大于2
        if (length <= 1) {
            return new OperateData(-1, Integer.class);
        }
        int base = Integer.parseInt(object.toString());
        if (length == 2) {
            OperateData operateData1 = arraySwap.get(1);
            Object object1 = operateData1.getObject(instructionSetContext);
            if (object1 == null) {
                return new OperateData(-1, Integer.class);
            }
            final int res = Integer.parseInt(object1.toString());
            if (res < 0) {
                return new OperateData(-1, Integer.class);
            } else if (res == 0) {
                return new OperateData(-1, Integer.class);
            } else if (res == 1) {
                return new OperateData(base + 1, Integer.class);
            } else {
                return new OperateData(base, Integer.class);
            }
        }
        //当前数值为非0
        OperateData compareData;
        List<Integer> resList = new ArrayList<>(arraySwap.length);
        int total = 0;
        for (int i = 1; i < length; i++) {
            compareData = arraySwap.get(i);
            final Object objectInner = compareData.getObjectInner(instructionSetContext);
            int i1 = objectInner == null ? 0 : Integer.parseInt(objectInner.toString());
            i1 = Math.max(i1, 0);
            resList.add(i1);
            total += i1;
        }

        if (total == 0) {
            return new OperateData(-1, Integer.class);
        }

        for (int i = 0; i < resList.size(); i++) {
            int tmp = base + i * 3;
            final int cur = resList.get(i);
            if (cur == total) {
                return new OperateData(tmp, Integer.class);
            }
            if (cur == 1) {
                return new OperateData(tmp + 1, Integer.class);
            }
            if (cur > 1 && cur < total) {
                return new OperateData(tmp + 2, Integer.class);
            }
        }
        return new OperateData(-2, Integer.class);
    }
}
